#pragma once
#include <sys/epoll.h>
#include <functional>
#include <memory>

class EventLoop;

using TaskCallBack = std::function<void()>;

class EventLoop;
class Channel{
public:
    Channel(EventLoop* loop);
    Channel(EventLoop* loop, int fd);
    ~Channel();
    
    void HandleEvents();
    inline void SetReadCallBack(const TaskCallBack& cb){
        readCallBack_ = cb;
    }
    inline void SetWriteCallBack(const TaskCallBack& cb){
        writeCallBack_ = cb;
    }
    inline void SetCloseCallBack(const TaskCallBack& cb){
        closeCallBack_ = cb;
    }
    inline void SetErrorCallBack(const TaskCallBack& cb){
        errorCallBack_ = cb;
    }

    inline int GetFd(){
        return fd_;
    }
    inline void SetFd(int fd){
        fd_=fd;
    }

    inline __uint32_t GetEvents(){
        return events_;
    }
    inline void SetREvents(__uint32_t revent){
        revents_ = revent;
    }
    inline void EnableReading(){
        events_ |= (EPOLLIN | EPOLLPRI);  
        Update();
    }

    inline void EnableWriting(){
        events_ |= (EPOLLOUT);  
        Update();
    }

private:
    void Update();

private:
    EventLoop* loop_;
    int fd_;

    __uint32_t events_;
    __uint32_t revents_;

    TaskCallBack readCallBack_;
    TaskCallBack writeCallBack_;
    TaskCallBack closeCallBack_;
    TaskCallBack errorCallBack_;
};

using ChannelPtr=std::shared_ptr<Channel>;